package com.erbao.datastructurearithmetic.tyro;

import java.util.Arrays;
import java.util.Objects;

/**
 * @author CaoBaoYin
 * @since 21/7/25 16:20
 */
public class Class2 {

    public static void main(String[] args) {
        int[] arr = {7,5,0,9,4,2,3,8,6};

        // int[] preSum = preSum(arr);
        // Arrays.stream(preSum).forEach(System.out::println);

        // System.out.println(rangeSum(arr,3,5));

        // 验证Math.random()产生每一个数都是等概率的
        int testTimes = 10000000;
        /*int count = 0;
        for (int i = 0; i < testTimes; i++) {
            if (Math.random() < 0.6) {
                count++;
            }
        }
        System.out.println((double) count / (double) testTimes);*///0.6002142

        // Math.random()*8 则产生每一个数[0,8)都是等概率的
        /*int count = 0;
        for (int i = 0; i < testTimes; i++) {
            if (Math.random()*8 < 5) {
                count++;
            }
        }
        System.out.println((double) count / (double) testTimes);*///0.6246829

        // System.out.println((int)1.99999999); // 1 强转是直接截断小数位

        int count = 0;
        int[] counts = new int[8];
        for (int i = 0; i < testTimes; i++) {
            int index = zeroOrOne();
            counts[index]++;
        }
        for (int i = 0; i < 8; i++) {
            System.out.println("整数【"+i+"】出现的次数："+counts[i]);
        }


        /*int count = 0;
        for (int i = 0; i < testTimes; i++) {
            if (to01() == 0) {
                count++;
            }
        }
        System.out.println((double) count / (double) testTimes);*///0.3600617

    }

    private static int p(){
        return Math.random()<0.843467 ? 0:1;
    }

    private static int zeroOrOne(){
        int res;
        do {
            res = p();
        } while (res == p());
        return res;
    }

    /**
     * 1--5等概率返回一个整数
     */
    private static int oneToFive(){
        return (int) (Math.random()*5 + 1);
    }

    /**
     * 0 1 发生器
     */
    private static int to01() {
        int res;
        do {
            res = oneToFive();
        } while (res == 3);

        return res < 3 ? 0 : 1;
    }

    /**
     * 1--7对应的是0--6二进制，表示6需要三位二进制 111最大值为7
     * 有两种思路：0--6 + 1 -> 1--7; 0--7 0重做 -> 1--7
     */
    private static int zeroToSix(){
        int res;
        do {
            res = (to01()<<2) + (to01()<<1) + to01();
        } while (res == 7);//此处如果遇0重做，就已经达到目标
        return res;
    }

    /**
     * 1--7等概率返回一个整数
     */
    private static int oneToSeven() {
        return zeroToSix()+1;
    }

    /**
     * 概率[0,X)转[0,X平方)
     */
    private static double xToXpower2() {
        return Math.max(Math.random(), Math.random());
    }

    /**
     * 求一个数组的角标一定范围内的和
     */
    private static int rangeSum(int[] arr,int l, int r) {
        if (l<0 || r<0) {
            throw new IllegalArgumentException("角标参数应该大于0");
        }

        int[] preSum = preSum(arr);
        return l == 0 ? preSum[r] : preSum[r]-preSum[l-1];
    }

    /**
     * 前缀和数组
     */
    private static int[] preSum(int[] arr) {
        int n = arr.length;
        int[] res = new int[n];
        res[0] = arr[0];
        for (int i = 1; i < n; i++) {
            res[i] = res[i-1] + arr[i];
        }
        return res;
    }

}
